package com.example.everying.service.content.impl;

import ch.qos.logback.core.util.StringUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.everying.constant.ArticleStatus;
import com.example.everying.constant.OrderConstants;
import com.example.everying.constant.PointsConstant;
import com.example.everying.context.UserContext;
import com.example.everying.mapper.content.ActivityApplyMapper;
import com.example.everying.mapper.content.ActivityArticleMapper;
import com.example.everying.mapper.content.ActivityRatingMapper;
import com.example.everying.model.dto.content.ArtInfoDto;
import com.example.everying.model.entity.content.ActivityApply;
import com.example.everying.model.entity.content.ActivityArticle;
import com.example.everying.model.entity.content.ActivityAudit;
import com.example.everying.model.entity.order.BountyOrder;
import com.example.everying.model.entity.user.*;
import com.example.everying.model.vo.content.ActivityApplyVo;
import com.example.everying.model.vo.content.ActivityArticleVo;
import com.example.everying.model.vo.content.ApplyViewVo;
import com.example.everying.model.vo.user.UserInfoVo;
import com.example.everying.service.content.ActivityArticleService;
import com.example.everying.service.content.ActivityAuditService;
//import com.example.everying.service.order.OrderInfoService;
import com.example.everying.service.order.BountyOrderService;
import com.example.everying.service.user.*;
import com.example.everying.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: everything
 * @description: 实现层
 * @author: zw
 * @create: 2025-05-14 17:03
 **/
@Service
@Slf4j
public class ActivityArticleServiceImple extends ServiceImpl<ActivityArticleMapper, ActivityArticle> implements ActivityArticleService {
    private static final String PLATFORM_USER_ID = "1"; // 平台用户ID
    // 定义常量代替魔法值
    private static final String RATING_STATUS_KEY = "7";

    @Autowired
    private ActivityAuditService auditService;
    @Autowired
    private SensitiveWordReplaceUtils sensitiveWordReplaceUtils;
    @Autowired
    private UserBalanceService userBalanceService;

    @Autowired
    private UserScoreService userScoreService;
    @Autowired
    private BountyOrderService bountyOrderService;
    @Autowired
    private UserBalanceTransactionService userBalanceTransactionService;
    @Autowired
    private ActivityApplyServiceImple applyService;
    @Autowired
    private ActivityApplyMapper applyMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private ActivityRatingMapper ratingMapper;
    @Autowired
    private UserLabelRelService userLabelRelService;
    @Autowired
    private LabelService labelService;
    @Autowired
    private AliGreenModerationUtil textModerationUtil;
    @Autowired
    private PointsAccountService pointsAccountService;
    @Autowired
    private ActivityPointsConfigService activityPointsConfigService;
    @Autowired
    private PointsTransactionService transactionService;
    @Autowired
    private ActivityParticipationService activityParticipationService;


    @Transactional
    @Override
    public Boolean articleAdd(ActivityArticleVo ActivityArticleEntityVo) {
        ActivityArticle activityArticleEntity = new ActivityArticle();
        BeanUtil.copyProperties(ActivityArticleEntityVo, activityArticleEntity);
        UserEntity user = UserContext.getUser();
        activityArticleEntity.setId(RandomUtil.generateId());
        activityArticleEntity.setUserId(user.getId());
        activityArticleEntity.setCreateTime(LocalDateTime.now());
        activityArticleEntity.setUpdateTime(LocalDateTime.now());
        activityArticleEntity.setArtViewStatus(2);
        // 权重默认为5
        activityArticleEntity.setWeight(5);
        //文章帖子修改为已完成状态
//        if (activityArticleEntity.getType() == 0) {
//            activityArticleEntity.setStatus("3");
//        }
        if (ActivityArticleEntityVo.getType() == 3 && activityArticleEntity.getIsComment() != null) {
            activityArticleEntity.setIsComment(activityArticleEntity.getIsComment());
        } else if (ActivityArticleEntityVo.getType() == 3 && ActivityArticleEntityVo.getIsComment() == null) {
            activityArticleEntity.setIsComment(0);
        }
        //文章开始时间
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime start = activityArticleEntity.getStartTime();

        // 如果startTime为空或小于当前时间，则设为当前时间
        if (start == null || start.isBefore(now)) {
            activityArticleEntity.setStartTime(now);
        }
        //有效日期默认3天结束
//        if (activityArticleEntity.getEndTime() == null || activityArticleEntity.getEndTime().isBefore(now)) {
//            LocalDateTime startTime = activityArticleEntity.getStartTime();
//            activityArticleEntity.setEndTime(startTime.plusDays(3));
//        }
        // 处理图片 URL 数组 -> 字符串
        if (activityArticleEntity.getPictureUrl() != null) {
            String pictureUrlStr = String.join(",", activityArticleEntity.getPictureUrl());
            activityArticleEntity.setPictureUrlStr(pictureUrlStr); // 设置转换后的字符串字段
        }
        if (ObjectUtil.isEmpty(activityArticleEntity.getUserId())) {
            throw new CampusException("uid不能为空", 201);
        }
        if (activityArticleEntity.getType() == 1 || activityArticleEntity.getType() == 2) {
            if (activityArticleEntity.getMoney().compareTo(BigDecimal.ZERO) <= 0) {
                throw new CampusException("金额必须大于0", 201);
            }
        }
        if (activityArticleEntity.getTitle().isEmpty()) {
            throw new CampusException("请输入标题", 201);
        }
        String content = String.valueOf(activityArticleEntity.getContent());
        String contents = String.valueOf(activityArticleEntity.getContents());
        if (StringUtils.isBlank(content)  || StringUtils.isBlank(contents))  {
            throw new CampusException("请输入有效内容，不能为空或仅包含空格", 201);
        }
        //敏感词替换标题和内容
        boolean hasSensitiveTitle = textModerationUtil.containsProhibitedWords(activityArticleEntity.getTitle());
        boolean hasSensitiveContent = textModerationUtil.containsProhibitedWords(activityArticleEntity.getContent());
        // 如果存在敏感词，抛出异常或返回失败
        if (hasSensitiveTitle || hasSensitiveContent) {
            throw new CampusException("存在敏感内容，请检查后重新上传", 201);
        }
//        boolean hasSensitiveContents = false ;
//        if (activityArticleEntity.getContents()!= null&& !activityArticleEntity.getContents().isEmpty()) {
//            hasSensitiveContents = textModerationUtil.containsProhibitedWords(activityArticleEntity.getContents());
//        }
        boolean save = this.save(activityArticleEntity);
        if (save) {
            // 审批列表
            this.auditAdd(activityArticleEntity);
            // 领取首次发布悬赏积分
            if (activityArticleEntity.getType() == 2 || activityArticleEntity.getType() == 1) {
                // 领取首次发布悬赏积分 receiveFirstPublish(user.getId())
                if (receiveFirstPublish(user.getId())) {
                    // 领取每天首次发布悬赏积分
                    rewardForFirstPost(user.getId());
                }
                if (ActivityArticleEntityVo.getPoints() == null) {
                    ActivityArticleEntityVo.setPoints(0);
                }
                String orderNo = createOrder(activityArticleEntity, activityArticleEntity.getType() == 2 ? ActivityArticleEntityVo.getPoints() : 0);
                if (orderNo == null || orderNo.isEmpty()) {
                    throw new CampusException("创建订单失败", 201);
                }
                activityArticleEntity.setOrderNo(orderNo);
            }

            // 开始扣费
            if (activityArticleEntity.getType() == 2) {
                boolean isCheck = userService.checkUserBalance(user.getId(), activityArticleEntity.getMoney(), ActivityArticleEntityVo.getPoints());
                if (!isCheck) {
                    throw new CampusException("余额或者积分不足", 201);
                }
                String payPassword = ActivityArticleEntityVo.getPayPassword() == null ? "" : ActivityArticleEntityVo.getPayPassword();
                log.info("开始扣费");
                handleOrderAccepted(activityArticleEntity, payPassword, ActivityArticleEntityVo.getPoints());
            }
            return save;
        }

        return false;
    }

    // 判断是不是第一次发布悬赏,领取第一次发布悬赏的积分
    private Boolean receiveFirstPublish(String userId) {
        ActivityParticipation activityParticipation = activityParticipationService.getRewardConfigByType(userId, PointsConstant.First_USER_PUBLISH_POINTS);
        if (activityParticipation != null) {
            return true;
        }
        QueryWrapper<ActivityPointsConfig> configQueryWrapper = new QueryWrapper<>();
        configQueryWrapper.eq("type", PointsConstant.First_USER_PUBLISH_POINTS);
        ActivityPointsConfig pointsConfig = activityPointsConfigService.getOne(configQueryWrapper);
        if (pointsConfig == null) {
            return false;
        }
        boolean isExist = activityPointsConfigService.checkActivityConfigById(pointsConfig.getId());
        if (isExist) {
//            QueryWrapper<ActivityArticle> queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("user_id", userId);
//            queryWrapper.eq("type", 1).or().eq("type", 2);
//            queryWrapper.between("create_time", pointsConfig.getStartTime(), pointsConfig.getEndTime());
//            if (baseMapper.selectCount(queryWrapper) > 0) {
//                return false;
//            }
            activityParticipationService.add(userId, pointsConfig, "1");
        }

        return false;
    }

    /**
     * 领取每天首次发布悬赏的积分
     */
    @Transactional
    public Boolean rewardForFirstPost(String userId) {
        // 查询用户当天发布的第一条悬赏帖子
        ActivityArticle article = baseMapper.getFirstRewardPostToday(userId);
        if (article == null) {
            return false;
        }
        // 校验当天是否已发放过该奖励，防止重复领取
        int todayRewardCount = Math.toIntExact(activityParticipationService.lambdaQuery()
                .eq(ActivityParticipation::getUserId, userId)
                .eq(ActivityParticipation::getParticipationType, PointsConstant.EVERYDAY_USER_PUBLISH_POINTS) // 增加积分
                .ge(ActivityParticipation::getCreateTime, LocalDate.now().atStartOfDay())
                .lt(ActivityParticipation::getCreateTime, LocalDate.now().plusDays(1).atStartOfDay())
                .count());
        if (todayRewardCount > 0) {
            // 当天已发放过，不再重复奖励
            return false;
        }
        // 查询悬赏帖子奖励配置
        ActivityPointsConfig config = activityPointsConfigService.getRewardConfigByType(PointsConstant.EVERYDAY_USER_PUBLISH_POINTS);
        if (config == null) {
            return false;
        }
        boolean isExist = activityPointsConfigService.checkActivityConfigById(config.getId());
        if (isExist) {
            activityParticipationService.add(userId, config, "1");
            return true;
        }

//        // 更新积分账户
//        boolean updateResult = pointsAccountService.updatePoints(userId, config.getPoints());
//        if (!updateResult) {
//            return  false;
//        }
//        // 记录积分交易
//        PointsTransaction transaction = new PointsTransaction();
//        transaction.setUserId(userId);
//        transaction.setTransactionNo(WeChatUtil.generateOrderTradeNumber(OrderConstants.TRANSACTION_TYPE_PREFIX_POINTS));
//        transaction.setPointsChange(config.getPoints());
//        transaction.setTransactionType(1); // 增加积分
//        transaction.setStatus(1); // 启动状态
//        transaction.setDescription("发布第一条悬赏帖子奖励");
//        transaction.setCreateTime(LocalDateTime.now());
//
//        transactionService.save(transaction);
        return false;
    }

    /**
     * 创建悬赏订单
     *
     * @param activityArticle 活动文章对象
     * @param points          使用的积分数量
     * @return 订单编号
     */
    private String createOrder(ActivityArticle activityArticle, Integer points) {
        log.info("创建悬赏订单:文章id{},积分{}", activityArticle.getId(), points);
        BountyOrder bountyOrder = new BountyOrder();
        bountyOrder.setOrderNo(WeChatUtil.generateTradeNumber(OrderConstants.TRANSACTION_TYPE_PREFIX_ORDER));
        bountyOrder.setArticleId(activityArticle.getId());
        bountyOrder.setPublisherId(activityArticle.getUserId());
        bountyOrder.setOrderStatus(OrderConstants.ORDER_STATUS_WAIT);
        bountyOrder.setCashAmount(activityArticle.getMoney());
        bountyOrder.setBountyAmount(activityArticle.getMoney());
        bountyOrder.setPoints(0);
        bountyOrder.setPointsAmount(BigDecimal.ZERO);
        // 如果使用积分抵扣，重新计算订单各金额字段
        if (points != null && points > 0) {
            bountyOrder.setPoints(points);
            BigDecimal pointsAmount = BigDecimal.valueOf(points)   // Convert points to BigDecimal
                    .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);  // Divide by 1000 and round to 2 decimal places
            BigDecimal activityMoney = activityArticle.getMoney().subtract(pointsAmount);
            // 还要判断一下是不是抵扣的超出本身的金额了
            if (activityMoney.compareTo(BigDecimal.ZERO) < 0) {
                throw new CampusException("抵扣积分超出悬赏金额", 201);
            }
            bountyOrder.setBountyAmount(activityMoney.add(pointsAmount));
            bountyOrder.setPointsAmount(pointsAmount);
            bountyOrder.setCashAmount(activityMoney);

        }
        bountyOrder.setCreateTime(LocalDateTime.now());
        bountyOrder.setUpdateTime(LocalDateTime.now());
        log.info("bountyOrder:{}", bountyOrder);
        boolean save = bountyOrderService.save(bountyOrder);
        if (save) {
            // 更新订单号到文章
            UpdateWrapper<ActivityArticle> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("order_no", bountyOrder.getOrderNo());
            updateWrapper.eq("id", activityArticle.getId());
            baseMapper.update(activityArticle, updateWrapper);
        }
        return bountyOrder.getOrderNo();
    }

    /**
     * 更新订单信息
     * <p>
     * 根据传入的活动文章和积分信息更新订单，包括计算积分抵扣金额、设置支付人等操作
     * 并将订单号更新到对应的文章记录中
     *
     * @param activityArticle 活动文章对象，包含订单号等信息
     * @param points          使用的积分数量，用于抵扣部分金额
     * @param userId          支付用户的ID
     * @return 更新成功返回true，否则返回false
     */
    // 更新订单
    @Override
    public boolean updateOrder(ActivityArticle activityArticle, Integer points, String userId) {
        BountyOrder bountyOrder = bountyOrderService.getByOrderNo(activityArticle.getOrderNo());
        // 如果使用积分抵扣，重新计算订单各金额字段
        if (points != null && points > 0) {
            bountyOrder.setPoints(points);
            BigDecimal pointsAmount = BigDecimal.valueOf(points / 100);
            BigDecimal activityMoney = activityArticle.getMoney().subtract(pointsAmount);
            bountyOrder.setBountyAmount(activityMoney.add(pointsAmount));
            bountyOrder.setPointsAmount(pointsAmount);
            bountyOrder.setCashAmount(activityMoney);

        }
        bountyOrder.setPaymentId(userId);
        bountyOrder.setCreateTime(LocalDateTime.now());
        bountyOrder.setUpdateTime(LocalDateTime.now());
        boolean save = bountyOrderService.updateById(bountyOrder);
        int update = 0;
        if (save) {
            // 更新订单号到文章
            UpdateWrapper<ActivityArticle> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("order_no", bountyOrder.getOrderNo());
            updateWrapper.eq("id", activityArticle.getId());
            update = baseMapper.update(activityArticle, updateWrapper);
        }
        return update > 0;
    }


    /**
     * 处理已接单状态的订单
     * 创建订单并从相应用户扣除款项
     *
     * @param activityArticle 活动文章对象，包含扣款金额和用户信息
     * @throws RuntimeException 如果创建订单失败，则抛出运行时异常
     */
    private void handleOrderAccepted(ActivityArticle activityArticle, String payPassword, Integer points) {
        log.info("处理已接单状态的订单");
        if (activityArticle.getType() != 2) {
            return;
        }
        String userId = activityArticle.getUserId();
        BountyOrder bountyOrder = bountyOrderService.getByOrderNo(activityArticle.getOrderNo());

        BigDecimal amount = bountyOrder.getCashAmount();
        String userType = "买家";

        log.info("开始扣费，用户ID:{} 扣{}的钱", userId, userType);

        if (userId.isEmpty()) {
            log.info("userId为空");
            throw new CampusException("未找到用户", 201);
        }
        if (payPassword.isEmpty()) {
            throw new CampusException("支付密码不能为空", 201);
        }
        boolean isVerified = userService.verifyPassword(userId, payPassword);
        if (!isVerified) {
            throw new CampusException("支付密码错误", 201);
        }
        // 更新订单
        boolean update = updateOrder(activityArticle, points, userId);
        if (!update) {
            throw new CampusException("更新订单失败", 201);
        }
        // 实付金额大于0才扣款
        if (amount.compareTo(BigDecimal.ZERO) > 0) {
            // 5. 落库
            boolean isDeducted = userBalanceService.deductBalance(userId, amount);
            if (isDeducted) {
                UserBalanceEntity userBalance = userBalanceService.getBalanceByUserId(userId);
                createAndSaveTransaction(userId, activityArticle.getId(), amount,
                        userBalance.getAvailableAmount().subtract(amount),
                        OrderConstants.TYPE_USER_EXPENSE,
                        OrderConstants.USER_TYPE_USER
                );
            }

            // 给系统用户加钱
            log.info("开始给系统加钱");
            boolean isAdded = userBalanceService.addBalance(PLATFORM_USER_ID, amount);
            if (isAdded) {
                UserBalanceEntity platformBalance = userBalanceService.getBalanceByUserId(PLATFORM_USER_ID);
                createAndSaveTransaction(
                        PLATFORM_USER_ID,
                        activityArticle.getId(),
                        amount,
                        platformBalance.getAvailableAmount().add(amount),
                        OrderConstants.TYPE_PLATFORM_INCOME,
                        OrderConstants.USER_TYPE_PLATFORM
                );
            }
        }

        // 开始扣积分
        if (points != null && points > 0) {
            log.info("开始扣积分");
            pointsAccountService.minusPoints(userId, points, "积分抵扣");
        }
    }

    // 公共方法：创建并保存交易记录
    private void createAndSaveTransaction(String userId, String txId, BigDecimal changeAmount, BigDecimal balanceAfterChange,
                                          String txType, String userType) {
        log.info("开始保存交易记录，用户id{},业务id{},交易类型{}，用户类型{}", userId, txId, txType, userType);
        UserBalanceTransactionEntity transaction = new UserBalanceTransactionEntity();
        transaction.setUserId(userId);
        transaction.setTxId(userType.equals(OrderConstants.USER_TYPE_PLATFORM) ? "PL" + txId : txId);
        transaction.setChangeAmount(changeAmount);  // 微信单位为分
        transaction.setBalanceSnapshot(balanceAfterChange);
        transaction.setTxStatus(OrderConstants.TX_STATUS_SUCCESS);
        transaction.setTxType(txType);
        transaction.setRemark("用户预付款");
        transaction.setUserType(userType);
        transaction.setType(OrderConstants.ORDER_TYPE_PREPAY);
        boolean result = userBalanceTransactionService.save(transaction);
        log.info("保存交易结果：{}", result ? "成功" : "失败");
    }

    /**
     * 审批列表
     *
     * @param article
     */
    private void auditAdd(ActivityArticle article) {
        UserEntity user = UserContext.getUser();
        ActivityAudit audit = new ActivityAudit();
        audit.setId(RandomUtil.generateId());
        audit.setRequestedBy(article.getUserId());
        audit.setArticleId(article.getId());
        audit.setStatus(0);
        audit.setCreateTime(new Date());
        audit.setCreator(article.getUserId());
        //TODO 审核人
        audit.setAdminReviewed("");
        auditService.save(audit);
    }

    /**
     * 分页查询
     *
     * @param pageParam
     * @param applyVo
     * @return
     */
    @Override
    public IPage<ActivityArticle> selectPage(Page<ActivityArticle> pageParam, ActivityArticleVo applyVo) {
        //创建查询wrapper
        ActivityArticle content = new ActivityArticle();
        BeanUtil.copyProperties(applyVo, content);
        QueryWrapper<ActivityArticle> wrapper = this.creatQueryWrapper();
        if (content.getTitle() != null && !content.getTitle().equals("")) {
            wrapper.like("title", content.getTitle());
        }
        //调用mapper的方法
        IPage<ActivityArticle> pages = baseMapper.selectPage(pageParam, wrapper);
        updateAndReturnIds();
        return pages;
    }
@Override
@Transactional(rollbackFor = Exception.class)
public Page<ActivityArticleVo> selectPageWithUser(Page<ActivityArticleVo> pageParam, ActivityArticleVo activityArticleVo) {
    log.info("开始查询文章列表，查询条件: {}", activityArticleVo);

    activityArticleVo.setEndTime(LocalDateTime.now());

    // 如果前端传递了位置信息，将位置筛选条件传入SQL查询
    if (activityArticleVo != null && activityArticleVo.getLocation() != null && !activityArticleVo.getLocation().isEmpty()) {
        log.info("检测到位置信息，将在SQL中进行位置筛选: {}", activityArticleVo.getLocation());

        String locationStr = activityArticleVo.getLocation();
        // 解析格式：搜索经度,搜索纬度,范围|用户经度,用户纬度
        String[] locationGroups = locationStr.split("\\|");

        // 只处理搜索位置（用于范围筛选）
        if (locationGroups.length > 0 && !locationGroups[0].isEmpty()) {
            String[] searchParts = locationGroups[0].split(",");
            if (searchParts.length >= 3) {
                try {
                    double searchLng = Double.parseDouble(searchParts[0].trim());
                    double searchLat = Double.parseDouble(searchParts[1].trim());
                    double filterRange = Double.parseDouble(searchParts[2].trim());

                    // 验证参数有效性
                    if (Math.abs(searchLat) > 90 || Math.abs(searchLng) > 180 || filterRange <= 0) {
                        log.warn("搜索参数超出有效范围: 经度={}, 纬度={}, 范围={}", searchLng, searchLat, filterRange);
                    } else {
                        log.info("位置筛选 - 经度: {}, 纬度: {}, 筛选范围: {}米", searchLng, searchLat, filterRange);

                        // 调用支持位置筛选的SQL方法
                        Page<ActivityArticleVo> pageModel = baseMapper.selectPageWithUserAndLocation(
                                pageParam, activityArticleVo, searchLng, searchLat, filterRange);

                        // 异步处理非关键操作
                        executeAsyncTasks();
                        return pageModel;
                    }
                } catch (NumberFormatException e) {
                    log.warn("位置信息格式错误: {}", locationGroups[0]);
                }
            }
        }
    } else {
        log.info("未传递位置信息，返回所有数据");
    }

    // 原有逻辑：不带位置筛选的查询
    Page<ActivityArticleVo> pageModel = baseMapper.selectPageWithUser(pageParam, activityArticleVo);

    // 异步处理非关键操作
    executeAsyncTasks();
    return pageModel;
}

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public Page<ActivityArticleVo> selectPageWithUser(Page<ActivityArticleVo> pageParam, ActivityArticleVo activityArticleVo) {
//        log.info("开始查询文章列表，查询条件: {}", activityArticleVo);
//
//        activityArticleVo.setEndTime(LocalDateTime.now());
//
//        // 调用自定义SQL方法
//        Page<ActivityArticleVo> pageModel = baseMapper.selectPageWithUser(pageParam, activityArticleVo);
//
//        // 如果前端传递了位置信息，进行简单的位置筛选
//        if (activityArticleVo != null && activityArticleVo.getLocation() != null && !activityArticleVo.getLocation().isEmpty()) {
//            log.info("检测到位置信息，开始进行位置筛选: {}", activityArticleVo.getLocation());
//
//            String locationStr = activityArticleVo.getLocation();
//
//            // 解析格式：搜索经度,搜索纬度,范围|用户经度,用户纬度
//            String[] locationGroups = locationStr.split("\\|");
//
//            // 只处理搜索位置（用于范围筛选）
//            if (locationGroups.length > 0 && !locationGroups[0].isEmpty()) {
//                String[] searchParts = locationGroups[0].split(",");
//                if (searchParts.length >= 3) {
//                    try {
//                        double searchLng = Double.parseDouble(searchParts[0]);
//                        double searchLat = Double.parseDouble(searchParts[1]);
//                        double filterRange = Double.parseDouble(searchParts[2]);
//
//                        log.info("位置筛选 - 经度: {}, 纬度: {}, 筛选范围: {}米", searchLng, searchLat, filterRange);
//
//                        // 筛选在范围内的文章
//                        List<ActivityArticleVo> records = pageModel.getRecords();
//                        List<ActivityArticleVo> filteredRecords = records.stream()
//                                .filter(article -> isWithinRange(article, searchLat, searchLng, filterRange))
//                                .collect(Collectors.toList());
//
//                        log.info("位置筛选完成 - 原始数据: {} 条，筛选后: {} 条", records.size(), filteredRecords.size());
//
//                        // 更新分页结果
//                        pageModel.setRecords(filteredRecords);
//                        pageModel.setTotal(filteredRecords.size());
//
//                    } catch (NumberFormatException e) {
//                        log.warn("位置信息格式错误: {}", locationGroups[0]);
//                    }
//                }
//            }
//        } else {
//            log.info("未传递位置信息，返回所有数据");
//        }
//
//        // 异步处理非关键操作
//        executeAsyncTasks();
//        return pageModel;
//    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public Page<ActivityArticleVo> selectPageWithUser(Page<ActivityArticleVo> pageParam, ActivityArticleVo activityArticleVo) {
//        long methodStartTime = System.currentTimeMillis();
//        log.info("开始查询文章列表，查询条件: {}", activityArticleVo);
//
//        activityArticleVo.setEndTime(LocalDateTime.now());
//
//        // 限制最大分页大小，避免一次性查询过多数据
//        long maxPageSize = 50;
//        if (pageParam.getSize() > maxPageSize) {
//            pageParam.setSize(maxPageSize);
//            log.warn("分页大小超过限制，已调整为: {}", maxPageSize);
//        }
//
//        long queryStartTime = System.currentTimeMillis();
//        // 调用自定义SQL方法
//        Page<ActivityArticleVo> pageModel = baseMapper.selectPageWithUser(pageParam, activityArticleVo);
//        long queryTime = System.currentTimeMillis() - queryStartTime;
//        log.info("数据库查询耗时: {} ms, 返回记录数: {}", queryTime, pageModel.getRecords().size());
//
//        // 如果前端传递了位置信息，进行简单的位置筛选
//        if (activityArticleVo != null && activityArticleVo.getLocation() != null && !activityArticleVo.getLocation().isEmpty()) {
//            log.info("检测到位置信息，开始进行位置筛选: {}", activityArticleVo.getLocation());
//
//            String locationStr = activityArticleVo.getLocation();
//
//            // 解析格式：搜索经度,搜索纬度,范围|用户经度,用户纬度
//            String[] locationGroups = locationStr.split("\\|");
//
//            // 只处理搜索位置（用于范围筛选）
//            if (locationGroups.length > 0 && !locationGroups[0].isEmpty()) {
//                String[] searchParts = locationGroups[0].split(",");
//                if (searchParts.length >= 3) {
//                    try {
//                        double searchLng = Double.parseDouble(searchParts[0]);
//                        double searchLat = Double.parseDouble(searchParts[1]);
//                        double filterRange = Double.parseDouble(searchParts[2]);
//
//                        log.info("位置筛选 - 经度: {}, 纬度: {}, 筛选范围: {}米", searchLng, searchLat, filterRange);
//
//                        // 位置筛选时间监控
//                        long filterStartTime = System.currentTimeMillis();
//
//                        // 筛选在范围内的文章
//                        List<ActivityArticleVo> records = pageModel.getRecords();
//                        List<ActivityArticleVo> filteredRecords = records.stream()
//                                .filter(article -> isWithinRangeOptimized(article, searchLat, searchLng, filterRange))
//                                .collect(Collectors.toList());
//
//                        long filterTime = System.currentTimeMillis() - filterStartTime;
//                        log.info("位置筛选完成 - 原始数据: {} 条，筛选后: {} 条，耗时: {} ms",
//                                records.size(), filteredRecords.size(), filterTime);
//
//                        // 更新分页结果
//                        pageModel.setRecords(filteredRecords);
//                        pageModel.setTotal(filteredRecords.size());
//
//                    } catch (NumberFormatException e) {
//                        log.warn("位置信息格式错误: {}", locationGroups[0]);
//                    }
//                }
//            }
//        } else {
//            log.info("未传递位置信息，返回所有数据");
//        }
//
//        // 异步处理非关键操作，避免阻塞主查询
//        executeAsyncTasks();
//
//        long methodTotalTime = System.currentTimeMillis() - methodStartTime;
//        log.info("方法总耗时: {} ms", methodTotalTime);
//
//        return pageModel;
//    }

    // 优化的位置筛选算法
    private boolean isWithinRangeOptimized(ActivityArticleVo article, double searchLat, double searchLng, double filterRange) {
        if (article.getLatAndLon() == null || article.getLatAndLon().isEmpty()) {
            return true;
        }

        String[] articleLocation = article.getLatAndLon().split(",");
        if (articleLocation.length != 2) {
            return true; // 位置格式错误，默认包含
        }

        try {
            double articleLng = Double.parseDouble(articleLocation[0]);
            double articleLat = Double.parseDouble(articleLocation[1]);

            // 粗略筛选，避免复杂的距离计算
            double latDiff = Math.abs(articleLat - searchLat);
            double lngDiff = Math.abs(articleLng - searchLng);

            // 1度约等于111公里，先进行粗略判断
            if (latDiff * 111000 > filterRange && lngDiff * 111000 > filterRange) {
                return false;
            }

            // 如果粗略筛选通过，再进行精确计算
            double distance = calculateDistance(searchLat, searchLng, articleLat, articleLng);
            boolean inRange = distance <= filterRange;

            log.debug("文章ID: {}, 距离: {}米, 是否在范围内: {}",
                    article.getId(), Math.round(distance), inRange);

            return inRange;

        } catch (NumberFormatException e) {
            log.warn("文章位置信息格式错误: {}, 文章ID: {}", article.getLatAndLon(), article.getId());
            return true; // 格式错误，默认包含
        }
    }

    // 异步执行非关键任务
    @Async
    protected void executeAsyncTasks() {
        try {
            long startTime = System.currentTimeMillis();
            updateAndReturnIds();
            updateStatusTime();
            long totalTime = System.currentTimeMillis() - startTime;
            log.info("异步任务执行完成，耗时: {} ms", totalTime);
        } catch (Exception e) {
            log.error("异步执行任务失败", e);
        }
    }


    /**
     * 判断文章是否在指定范围内
     *
     * @param article     文章
     * @param searchLat   搜索纬度
     * @param searchLng   搜索经度
     * @param filterRange 筛选范围（米）
     * @return 是否在范围内
     */
    private boolean isWithinRange(ActivityArticleVo article, double searchLat, double searchLng, double filterRange) {
        if (article.getLatAndLon() == null || article.getLatAndLon().isEmpty()) {
            // 没有位置信息的文章默认包含在结果中
            return true;
        }

        String[] articleLocation = article.getLatAndLon().split(",");
        if (articleLocation.length != 2) {
            return true; // 位置格式错误，默认包含
        }

        try {
            double articleLng = Double.parseDouble(articleLocation[0]);
            double articleLat = Double.parseDouble(articleLocation[1]);

            double distance = calculateDistance(searchLat, searchLng, articleLat, articleLng);
            boolean inRange = distance <= filterRange;

            log.debug("文章ID: {}, 距离: {}米, 是否在范围内: {}",
                    article.getId(), Math.round(distance), inRange);

            return inRange;

        } catch (NumberFormatException e) {
            log.warn("文章位置信息格式错误: {}, 文章ID: {}", article.getLatAndLon(), article.getId());
            return true; // 格式错误，默认包含
        }
    }

    /**
     * 使用Haversine公式计算两点间距离
     *
     * @param lat1 纬度1
     * @param lng1 经度1
     * @param lat2 纬度2
     * @param lng2 经度2
     * @return 距离（米）
     */
    private double calculateDistance(double lat1, double lng1, double lat2, double lng2) {
        final double EARTH_RADIUS = 6371000; // 地球半径，单位：米

        double lat1Rad = Math.toRadians(lat1);
        double lat2Rad = Math.toRadians(lat2);
        double deltaLat = Math.toRadians(lat2 - lat1);
        double deltaLng = Math.toRadians(lng2 - lng1);

        double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
                Math.cos(lat1Rad) * Math.cos(lat2Rad) *
                        Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2);

        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        return EARTH_RADIUS * c;
    }

    @Override
    public Page<ActivityArticle> bannerPage(Page<ActivityArticle> pageParam, ActivityArticle queryVo) {
        // 校验分页参数非空
        if (pageParam == null) {
            pageParam = new Page<>();
        }

        // 构建查询条件：类型固定为3，同时支持其他查询条件
        QueryWrapper<ActivityArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", 3);

        if (queryVo != null) {
            if (StringUtils.isNotEmpty(queryVo.getTitle())) {
                queryWrapper.like("title", queryVo.getTitle());
            }
        }
        baseMapper.selectPage(pageParam, queryWrapper);
        // 直接返回填充了结果的分页对象
        return pageParam;
    }

    /**
     * 补充订单记录
     *
     * @return
     */
    @Override
    public Boolean articleAdd2() {
        QueryWrapper<ActivityArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete", 0);
        queryWrapper.eq("type", 1).or().eq("type", 2);
        List<ActivityArticle> list = baseMapper.selectList(queryWrapper);
        log.info("list size:" + list.size());
        list.forEach(article -> {
            createOrder(article, 0);
        });
        log.info("补充订单数据完毕");
        return true;
    }

    @Override
    public String getUserPhone(String articleId) {
        UserEntity user = UserContext.getUser();
        ActivityArticle article = baseMapper.getArticleById(articleId);
        if (article == null || user == null) {
            log.info("文章或用户信息为空");
            throw new CampusException("没有权限", 201);
        }
        // 文章状态 1-进行中 2-未开始 3-已完成; 4：失效
        if ("1".equals(article.getStatus()) || "3".equals(article.getStatus())) {
            String targetUserId = null;
            if (article.getUserId() != null && article.getUserId().equals(user.getId())) {
                targetUserId = article.getApplyId();
            } else if (article.getApplyId() != null && article.getApplyId().equals(user.getId())) {
                targetUserId = article.getUserId();
            }

            if (targetUserId != null) {
                UserEntity userEntity = userService.getById(targetUserId);
                if (userEntity != null) {
                    return userEntity.getPhone();
                }
            }
        }

        log.info("文章状态异常");
        throw new CampusException("没有权限", 201);
    }

    /**
     * 获取内容信息是否存在
     *
     * @param cid
     * @return
     */
    @Override
    public ActivityAudit getByCid(String cid) {
        ActivityArticle article = this.getById(cid);
        // 获取发表内容信息
        if (ObjectUtil.isEmpty(article)) {
            throw new CampusException("发表内容信息不存在", 201);
        }
        return auditService.getOne(new QueryWrapper<ActivityAudit>().eq("article_id", article.getId()));
    }

    /**
     * 更新状态时间
     */
    public void updateStatusTime() {
        try {
            QueryWrapper<ActivityArticle> wrapper = new QueryWrapper<>();
            wrapper.eq("status", 4);
            wrapper.eq("is_delete", 0);
            wrapper.in("type", 1, 2);
            wrapper.gt("end_time", LocalDateTime.now());
            List<ActivityArticle> articles = baseMapper.selectList(wrapper);

            if (articles.isEmpty()) {
                return;
            }
            // 批量更新
            List<ActivityArticle> updateList = new ArrayList<>();
            articles.forEach(article -> {
                ActivityArticle activityArticle = new ActivityArticle();
                activityArticle.setId(article.getId());
                activityArticle.setStatus("2"); // 根据逻辑分析，这里应该是固定值2
                updateList.add(activityArticle);
            });
            // 执行批量更新
            updateBatchById(updateList);
        } catch (Exception e) {
            throw new RuntimeException("更新状态时间失败", e);
        }
    }

    @Override
    public void viewsEdit(String id) {
        ActivityArticle activityArticle = baseMapper.selectById(id);
        activityArticle.setViews(activityArticle.getViews() + 1);
        baseMapper.updateById(activityArticle);
    }

    @Override
    public boolean updateLikesCount(String articleId, Integer count) {
        ActivityArticle article = new ActivityArticle();
        article.setId(articleId);
        article.setThumbs(count);
        return updateById(article);
    }

    /**
     * 返回接单用户的信息，如果自动接单状态回显私密信息
     *
     * @param articleId
     * @return
     */
    @Override
    public ActivityArticleVo articleId(String articleId) {
        ActivityArticleVo articleVo = baseMapper.articleId(articleId);
        if (articleVo != null && UserContext.getUser() != null) {
            List<ActivityApplyVo> activityApplyVos = applyMapper.selectArtId(articleVo.getId(), UserContext.getUser().getId());
            articleVo.setApplicationList(activityApplyVos);
        }
        if (articleVo != null && articleVo.getUserId() != null) {
            List<UserLabelRelEntity> labelByUserId = userLabelRelService.getLabelByUserId(articleVo.getUserId());
            if (labelByUserId == null || labelByUserId.size() == 0) {
                return articleVo;
            }
            List<String> labelIds = labelByUserId.stream().map(UserLabelRelEntity::getLabelId).collect(Collectors.toList());
            List<LabelEntity> labelPicUrls = labelService.getLabelPicUrls(labelIds);
            articleVo.setLabel(labelPicUrls);
        }
        return articleVo;
    }

    /**
     * 发布列表
     *
     * @param pageParam
     * @param userId
     * @param tokenId
     * @param status
     * @return
     */
    @Override
    public IPage<ActivityArticleVo> publishSelect(Page<ActivityArticleVo> pageParam, String userId, String tokenId, String status) {
        if (StringUtil.notNullNorEmpty(status) && status.equals("5")) {
            return baseMapper.selectStatus(pageParam, userId, null, tokenId);
        } else if (StringUtil.notNullNorEmpty(status) && status.equals("6")) {
            IPage<ActivityArticleVo> voIPage = baseMapper.selectAppealStatus(pageParam, userId, null, tokenId);
            voIPage.getRecords().forEach(a -> {
                if (userId.equals(a.getAppealUserId())) {
                    a.setRevoke("1");
                }
            });
            return voIPage;
        } else if (StringUtil.notNullNorEmpty(status) && status.equals("7")) {
            return ratingMapper.selectPublishedToRate(pageParam, userId);
        }
        return baseMapper.publishSelect(pageParam, userId, tokenId, status);
    }

    private void updateExpiredArticles() {
        baseMapper.updateEndTimeById(LocalDateTime.now());
    }

    @Transactional
    public void updateAndReturnIds() {
        UserInfoVo userInfoVo = UserContext.getUser();
        if (userInfoVo == null) {
            return;
        }
        // 1. 查询需要更新的ID
        List<ActivityArticle> articles = baseMapper.selectArticleIdsForUpdate(userInfoVo.getId(), LocalDateTime.now());
        List<String> ids = articles.stream().map(ActivityArticle::getId).collect(Collectors.toList());
        // 2. 执行更新
        if (!ids.isEmpty()) {
            baseMapper.updateEndTimeById(ids);
        }
        // 发送失效通知
        articles.forEach(article -> {
            // 发送失效通知
            String content = "您的悬赏已失效";
            ArtInfoDto artInfoDto = new ArtInfoDto();
            artInfoDto.setTitle(article.getTitle());
            artInfoDto.setIsMyRelease(true);
            artInfoDto.setArticleUserName(applyService.getUserNickname(article.getUserId()));
            artInfoDto.setArticleUserAvatar(applyService.getUserAvatar(article.getUserId()));
            applyService.sendSystemNotification(article.getUserId(), "您的悬赏已失效", content, "0", JSON.toJSONString(artInfoDto));
        });
    }

    @Override
    public IPage<ActivityArticleVo> parSelect(Page<ActivityArticleVo> pageParam, String userId, String tokenId, String status) {
        if (StringUtil.notNullNorEmpty(status) && status.equals("5")) {
            return baseMapper.selectStatus(pageParam, null, userId, tokenId);
        } else if (StringUtil.notNullNorEmpty(status) && status.equals("6")) {
            IPage<ActivityArticleVo> voIPage = baseMapper.selectAppealStatus(pageParam, null, userId, tokenId);
            voIPage.getRecords().forEach(a -> {
                if (userId.equals(a.getAppealUserId())) {
                    a.setRevoke("1");
                }
            });
            return voIPage;
        } else if (StringUtil.notNullNorEmpty(status) && status.equals("7")) {
            return ratingMapper.selectParticipatedToRate(pageParam, userId);
        }
        return baseMapper.parSelect(pageParam, userId, tokenId, status);
    }

    /**
     * @param id
     * @return
     */
    @Override
    public ActivityArticle getArticleById(String id) {
        return baseMapper.getArticleById(id);
    }

    @Override
    public List<ActivityArticle> bannerList() {
        QueryWrapper<ActivityArticle> type = new QueryWrapper<ActivityArticle>().eq("type", 3);
        List<ActivityArticle> articles = baseMapper.selectList(type);
        // 获取今天的日期
        LocalDate today = LocalDate.now();
        // 过滤掉结束时间早于今天的文章
        return articles.stream()
                .filter(article -> {
                    LocalDateTime endTime = article.getEndTime();
                    // 如果结束时间为null，默认不过滤
                    if (endTime == null) {
                        return true;
                    }
                    // 将结束时间转换为LocalDate进行比较
                    LocalDate endDate = endTime.toLocalDate();
                    // 只保留结束日期大于等于今天的文章
                    return !endDate.isBefore(today);
                }).limit(3)
                .collect(Collectors.toList());
    }

    /**
     * 注销账户的文章更改为失效状态
     *
     * @param userId
     * @return
     */
    @Override
    @Transactional
    public boolean updateByUserID(String userId) {
        QueryWrapper<ActivityArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        List<ActivityArticle> articles = baseMapper.selectList(queryWrapper);
        if (articles.isEmpty()) {
            return true;
        }
        List<String> artIds = articles.stream().map(ActivityArticle::getId).toList();
        QueryWrapper<ActivityApply> applyQueryWrapper = new QueryWrapper<>();
        applyQueryWrapper.in("art_id", artIds);
        applyQueryWrapper.eq("orders_status", "1");
        List<ActivityApply> applyList = applyMapper.selectList(applyQueryWrapper);
        if (!applyList.isEmpty()) {
            throw new CampusException("有进行中的订单，请先取消订单", 201);
        }
        articles.forEach(article -> {
            if (article.getType() == 1) {
                BigDecimal amount = article.getMoney();
                handleOrderUpdateAmt(article, amount, "文章失效发起退款", "文章失效退回积分");
            }
        });
        baseMapper.updateByUserID(userId);
        return true;
    }

    @Override
    public List<ActivityArticle> getArticleByStatus(String status) {
        QueryWrapper<ActivityArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", status);
        return baseMapper.selectList(queryWrapper);
    }

    /**
     * @param article
     * @return
     */
    @Override
    @Transactional
    public Result<?> articleEdit(ActivityArticleVo article) {
        try {

            if (article.getTitle() != null || article.getContent() != null) {
                //敏感词替换标题和内容
                boolean hasSensitiveTitle = textModerationUtil.containsProhibitedWords(article.getTitle());
                boolean hasSensitiveContent = textModerationUtil.containsProhibitedWords(article.getContent());

                // 如果存在敏感词，抛出异常或返回失败
                if (hasSensitiveTitle || hasSensitiveContent) {
                    return Result.fail("文章包含敏感内容，请检查后再提交");
                }
            }
            ActivityArticle activityArticle = baseMapper.articleId(article.getId());
            if (article.getStatus() != null && article.getStatus().equals("3") && !activityArticle.getAppealStatus().equals("0")) {
                QueryWrapper<ActivityApply> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("art_id", article.getId());
                queryWrapper.in("orders_status", Arrays.asList("1", "3")); // 修改点：支持多个状态
                ActivityApply apply = applyService.getOne(queryWrapper);
                if (apply == null) {
                    return Result.fail("该帖子没有接单人不能完成");
                }
                UpdateWrapper<BountyOrder> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("order_no", activityArticle.getOrderNo());
                if (apply.getOrdersStatus().equals("3")) {
                    log.info("申请人已完成，开始打款");
                    // 开始扣钱
                    handleOrderCompleted(activityArticle);
                    updateWrapper.set("order_status", OrderConstants.ORDER_STATUS_COMPLETE);
                    // 判断申请人是不是首次是的话要奖励积分
                    handleActivityPoints(activityArticle);
                    // 给文章发布者加信誉值
//                    userScoreService.updateMonthlyCreditIncrement(activityArticle.getUserId(), 0.1);
                }
                updateWrapper.set("order_status", OrderConstants.ORDER_STATUS_WAIT_ACCEPT);
                bountyOrderService.update(updateWrapper);
                //发布者点击完成申请者待查看
                apply.setAppViewStatus(2);
                applyMapper.updateById(apply);
                //发送申请处理结果通知(通知申请者)
                ActivityApplyVo applyVo = new ActivityApplyVo();
                BeanUtil.copyProperties(apply, applyVo);
                activityArticle.setStatus(article.getStatus());
                applyService.sendApplyApplicationResultNotification(applyVo, activityArticle);
            }
            // 判断一下是否修改价格,若修改价格，则需要扣除金额，并把之前的钱退款
            if (article.getMoney() != null && activityArticle.getMoney().compareTo(article.getMoney()) != 0) {
                // 判断有没有人接单，要是有人接单就不能修改价格了
                QueryWrapper<ActivityApply> queryWrapper = new QueryWrapper<>();
                List<String> status = new ArrayList<>(2);
                status.add("1");
                status.add("3");
                queryWrapper.eq("art_id", article.getId());
                queryWrapper.in("orders_status", status);
                ActivityApply apply = applyService.getOne(queryWrapper);
                if (apply != null) {
                    return Result.fail("该帖子有接单人，不能修改价格");
                }

                if (activityArticle.getType() == 2) {
                    log.info("修改价格，开始扣除发布者金额");
                    UserInfoVo user = UserContext.getUser();
                    boolean isCheck = userService.checkUserBalance(user.getId(), article.getMoney(), article.getPoints());
                    if (!isCheck) {
                        throw new CampusException("余额或者积分不足", 201);
                    }
                    BountyOrder bountyOrder = bountyOrderService.getByOrderNo(activityArticle.getOrderNo());
                    if (bountyOrder == null) {
                        throw new CampusException("订单不存在", 201);
                    }
                    // 异步把钱退回去
                    handleOrderCancelled(activityArticle, bountyOrder.getCashAmount(), "发布者修改价格,退回积分");
                    // 更新订单信息
                    bountyOrder.setBountyAmount(article.getMoney());
                    activityArticle.setMoney(article.getMoney());
                    BigDecimal amount = applyService.calculatePointsAmount(activityArticle, article.getPoints());
                    bountyOrder.setPointsAmount(article.getMoney().subtract(amount));
                    bountyOrder.setCashAmount(amount);
                    bountyOrder.setUpdateTime(LocalDateTime.now());
                    bountyOrderService.updateById(bountyOrder);
                    String payPassword = article.getPayPassword() == null ? "" : article.getPayPassword();
                    // 重新扣除用户金额
                    handleOrderAccepted(activityArticle, payPassword, article.getPoints());

                } else if (activityArticle.getType() == 1) {
                    log.info("修改价格，开始退还申请人金额");
                    BigDecimal amount = activityArticle.getMoney();
                    handleOrderUpdateAmt(activityArticle, amount, "发布人修改价格退款", "发布人修改价格退回积分");
                }
            }

            article.setUpdateTime(LocalDateTime.now());
            article.setUpdater(UserContext.getUser().getId());
            baseMapper.updateById(article);
            return Result.ok();
        } catch (CampusException e) {
            // 处理自定义业务异常
            log.error("业务异常：{}", e.getMessage(), e);
            return Result.fail(e.getMessage());
        } catch (Exception e) {
            // 捕获其他未知异常
            log.error("系统异常：{}", e.getMessage(), e);
            return Result.fail("网络错误，请稍后再试");
        }
    }

    // 处理活动积分领取记录
    @Override
    public void handleActivityPoints(ActivityArticle activityArticle) {
        ActivityParticipation activityParticipation = activityParticipationService.getRewardConfigByType(activityArticle.getApplyId(), PointsConstant.FIRST_USER_ACCEPT_POINTS);
        if (activityParticipation == null) {
            log.info("该用户是首次申请，开始处理活动积分");
            // 查询悬赏帖子奖励配置
            ActivityPointsConfig config = activityPointsConfigService.getRewardConfigByType(PointsConstant.FIRST_USER_ACCEPT_POINTS);
            if (config == null) {
                return;
            }
            boolean isExist = activityPointsConfigService.checkActivityConfigById(config.getId());
            if (isExist) {
                activityParticipationService.add(activityArticle.getApplyId(), config, "1");
            }
        } else {
            // 处理每日完成的
            // 校验当天是否已发放过该奖励，防止重复领取
            int todayRewardCount = Math.toIntExact(activityParticipationService.lambdaQuery()
                    .eq(ActivityParticipation::getUserId, activityArticle.getApplyId())
                    .eq(ActivityParticipation::getParticipationType, PointsConstant.EVERYDAY_USER_COMPLETE_POINTS) // 增加积分
                    .ge(ActivityParticipation::getCreateTime, LocalDate.now().atStartOfDay())
                    .lt(ActivityParticipation::getCreateTime, LocalDate.now().plusDays(1).atStartOfDay())
                    .count());
            if (todayRewardCount > 0) {
                // 当天已发放过，不再重复奖励
                return;
            }
            // 查询悬赏帖子奖励配置
            ActivityPointsConfig config = activityPointsConfigService.getRewardConfigByType(PointsConstant.EVERYDAY_USER_COMPLETE_POINTS);
            if (config == null) {
                return;
            }
            boolean isExist = activityPointsConfigService.checkActivityConfigById(config.getId());
            if (isExist) {
                activityParticipationService.add(activityArticle.getApplyId(), config, "1");
            }
        }
    }

    @Override
    public ApplyViewVo artView(String userId) {
        List<ApplyViewVo> applyList = baseMapper.selectArtUserId(userId);

        if (applyList == null || applyList.isEmpty()) {
            return null;
        }

        // 按字符串状态字段分组统计数量
        Map<String, Long> statusCountMap = applyList.stream()
                .filter(apply -> apply.getVirtualStatus() != null)
                .collect(Collectors.groupingBy(
                        ApplyViewVo::getVirtualStatus,
                        // 统计未读条数
                        Collectors.filtering(
                                apply -> apply.getArtViewStatus() != 1 &&
                                        apply.getArtViewType() != 0 &&
                                        apply.getArtViewType() != 3,
                                Collectors.counting() // 统计过滤后数量
                        )
                ));
        // 添加评价的未读数量
        long ratingCount = ratingMapper.selectPublishedToRateCount(userId);
        statusCountMap.put(RATING_STATUS_KEY, ratingCount);
        log.info("状态Map：{}", statusCountMap);
        // 创建汇总结果对象
        ApplyViewVo result = new ApplyViewVo();
        // 设置状态统计 Map
        result.setStatusCountMap(statusCountMap);

        // 已读/未读统计
        long readCount = applyList.stream()
                .filter(apply -> apply.getArtViewStatus() == 1 ||
                        apply.getArtViewType() == 0 ||
                        apply.getArtViewType() == 3)
                .count();

        long unreadCount = applyList.size() - readCount;

        result.setReadCount(readCount);
        result.setUnreadCount(unreadCount);

        System.out.println("状态Map：" + result.getStatusCountMap());
        System.out.println("已读条数：" + result.getReadCount());
        System.out.println("未读条数：" + result.getUnreadCount());
        return result;
    }

    @Override
    public ApplyViewVo appView(String userId) {
        List<ApplyViewVo> applyList = baseMapper.selectAppUserId(userId);

        if (applyList == null || applyList.isEmpty()) {
            return null;
        }

        // 按字符串状态字段分组统计数量
        Map<String, Long> statusCountMap = applyList.stream()
                .filter(apply -> apply.getOrdersStatus() != null)
                .collect(Collectors.groupingBy(
                        ApplyViewVo::getOrdersStatus,
                        Collectors.filtering(
                                apply -> apply.getAppViewStatus() != 1,
                                Collectors.counting() // 统计过滤后数量
                        )
                ));
        // 添加评价的状态
        long count = ratingMapper.selectParticipatedToRateCount(userId);
        statusCountMap.put(RATING_STATUS_KEY, count);
        log.info("状态Map：{}", statusCountMap);
        statusCountMap.put("2", 0L);
        // 创建汇总结果对象
        ApplyViewVo result = new ApplyViewVo();
        // 设置状态统计 Map
        result.setStatusCountMap(statusCountMap);
        // 统计已读和未读数量
        long readCount = applyList.stream()
                .filter(apply -> apply.getAppViewStatus() == 1 ||
                        apply.getOrdersStatus().equals("2") ||
                        apply.getOrdersStatus().equals("8"))
                .count();

        long unreadCount = applyList.size() - readCount;
        result.setReadCount(readCount);
        result.setUnreadCount(unreadCount);
        return result;
    }

    @Override
    public int artViewRead(String userId, String status, String artId) {
        // 处理页面待确认和申诉的状态
        if ("5".equals(status) || "6".equals(status)) {
            status = "1";
        }
        UpdateWrapper<ActivityArticle> updateWrapper = new UpdateWrapper<>();
        if (status != null) {
            updateWrapper.eq("status", status);
        } else if (artId != null) {
            updateWrapper.eq("id", artId);
        }
        updateWrapper.eq("user_id", userId)
                .set("art_view_status", 1);
        return baseMapper.update(null, updateWrapper);
    }

    @Override
    public int appViewRead(String status, String artId) {
        String userId = UserContext.getUser().getId();
        boolean hasSetField = false;
        // 处理页面待确认和申诉的状态
        if ("5".equals(status) || "6".equals(status)) {
            status = "1";
        }
        // 构建更新条件
        UpdateWrapper<ActivityApply> updateWrapper = new UpdateWrapper<>();
        int viewStatus = 1;
        // 根据状态设置未读状态
        if (StringUtils.isNotBlank(status)) {
            viewStatus = "2".equals(status) ? 2 : 1;
            updateWrapper.set("app_view_status", viewStatus);
            // 设置基础条件
            updateWrapper.eq(StringUtils.isNotBlank(userId), "user_id", userId);
            updateWrapper.eq("orders_status", status);
            hasSetField = true;
        }
        if (artId != null) {
            updateWrapper.eq("art_id", artId);
            hasSetField = true;
        }
        updateWrapper.set("app_view_status", viewStatus);
        // 判断是否为有效条件
        if (!hasSetField) {
            System.out.println("UpdateWrapper 为空，不执行更新操作");
            return 0;
        }
        // 执行更新操作
        return applyMapper.update(null, updateWrapper);
    }

    /**
     * @param id
     * @return
     */
    @Override
    @Transactional
    public Result<?> delete(String id) {
        QueryWrapper<ActivityApply> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("art_id", id);
        queryWrapper.in("orders_status", Arrays.asList("1", "3")); // 修改点：支持多个状态
        ActivityApply apply = applyService.getOne(queryWrapper);
        if (apply != null) {
            return Result.fail("该帖子已被接单不能删除");
        }
        ActivityArticle activityArticle = baseMapper.selectById(id);
        if (activityArticle.getType() == 2) {
            BountyOrder order = bountyOrderService.getByOrderNo(activityArticle.getOrderNo());
            BigDecimal amount = activityArticle.getMoney();
            if (order != null) {
                amount = order.getCashAmount();
            }
            // 开始退款
            handleOrderCancelled(activityArticle, amount, "用户删除帖子,退回积分");
        }
        UpdateWrapper<ActivityArticle> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id); // 确保只更新未删除的记录
        updateWrapper.set("is_delete", 1)
                .set("updater", UserContext.getUser().getId())
                .set("update_time", LocalDateTime.now());

        boolean success = baseMapper.update(updateWrapper) > 0;
        // 管理员发送通知
        if (UserContext.getUser().getIsAdministrator() == 1 || UserContext.getUser().getIsAdministrator() == 3) {
            sendNotice(activityArticle);
        }
        return success ? Result.ok("删除成功") : Result.fail("删除失败");
    }

    // 发送通知
    private void sendNotice(ActivityArticle activityArticle) {
//        String prefix = activityArticle.getTitle().substring(0, 2);
        String content = "因违反社区公约，您的帖子已被删除，请重新编辑后再次发布。";
        ArtInfoDto artInfoDto = new ArtInfoDto();
        artInfoDto.setTitle(activityArticle.getTitle());
        artInfoDto.setArticleUserName(userService.getUserNickname(activityArticle.getUserId()));
        artInfoDto.setArticleUserAvatar(userService.getUserAvatar(activityArticle.getUserId()));
        applyService.sendSystemNotification(activityArticle.getUserId(), "违规处理", content, "7", JSON.toJSONString(artInfoDto));

    }

    @Override
    public IPage<ActivityArticleVo> selectByUser(Page<ActivityArticleVo> pageParam, String userId, String status, String id) {
        IPage<ActivityArticleVo> activityArticleVoIPage = baseMapper.selectByUser(pageParam, userId, status, id);
        String localUserId = UserContext.getUser().getId();
        activityArticleVoIPage.getRecords().forEach(activityArticleVo -> {
            if (activityArticleVo.getOrdersStatus() != null && activityArticleVo.getStatus() != null) {
                activityArticleVo.setApplyStatus(getApplyStatus(activityArticleVo.getOrdersStatus(), activityArticleVo.getStatus(), activityArticleVo.getType()));
            } else if (activityArticleVo.getOrdersStatus() == null) {
                // 待申请
                if (activityArticleVo.getType() == 0 || activityArticleVo.getType() == 3) {
                    activityArticleVo.setApplyStatus("10");
                } else {
                    activityArticleVo.setApplyStatus("0");
                }
            }
            if (activityArticleVo.getApplyUserId() != null &&
                    ((activityArticleVo.getUserId().equals(localUserId) && activityArticleVo.getApplyUserId().equals(userId)) ||
                            (activityArticleVo.getUserId().equals(userId) && activityArticleVo.getApplyUserId().equals(localUserId)))) {
                activityArticleVo.setIsPublic(true);
            }
        });
        return activityArticleVoIPage;
    }

    /**
     * 处理申请状态
     *
     * @param ordersStatus  订单状态码
     * @param articleStatus 文章状态码
     * @return 状态码字符串
     * <p>
     * 状态码对应关系：
     * 0 - 待申请
     * 1 - 已接受
     * 2 - 待同意
     * 3 - 已完成
     * 4 - 已退出
     * 5 - 已拒绝
     * 6 - 待申请人确认
     * 7 - 待发布人确认
     * 8 - 已被申请
     * 9 - 已被他人完成
     */
    @Override
    public String getApplyStatus(String ordersStatus, String articleStatus, Integer articleType) {
        if (articleType == 0 || articleType == 3) {
            // 帖子单独处理
            return "10";
        }
        switch (ordersStatus) {
            case "3": // 已完成
                return articleStatus.equals("3") ? "3" : "7"; // 3=已完成, 7=待发布人确认
            case "5": // 已拒绝
                return "5";
            case "4": // 已退出
                return "4";
            case "2": // 待同意
                if (articleStatus.equals("1")) return "8"; // 8=已被申请
                if (articleStatus.equals("3")) return "9"; // 9=已被他人完成
                return "2"; // 2=待同意
            case "1": // 已接受
                return articleStatus.equals("3") ? "6" : "1"; // 6=待申请人确认, 1=已接受
            default:
                return "0"; // 0=带申请
        }
    }

    /**
     * 获取退款用户的ID
     * 根据活动类型判断是卖家还是买家
     *
     * @param activityArticle 活动文章对象，包含用户ID和活动类型
     * @return 退款用户的ID
     */
    public String getRefundUserId(ActivityArticle activityArticle) {
        return activityArticle.getType() == 1 ? activityArticle.getApplyId() : activityArticle.getUserId();
    }

    @Override
    public ActivityArticleVo artTask(ActivityArticleVo article) {
        return null;
    }

    /**
     * 处理已取消状态的订单
     * 向相应用户退款
     *
     * @param activityArticle 活动文章对象，包含退款金额和用户信息
     */
    @Async
    protected void handleOrderCancelled(ActivityArticle activityArticle, BigDecimal amount, String pointsMsg) {
        String userId = getRefundUserId(activityArticle);

        log.info("开始退钱，给{}退钱", userId);
        if (amount != null && amount.compareTo(BigDecimal.ZERO) > 0) {
            boolean isAdded = userBalanceService.addBalance(userId, amount);
            if (isAdded) {
                UserBalanceEntity userBalance = userBalanceService.getBalanceByUserId(userId);
                createAndSaveTransaction(
                        userId, activityArticle.getId(), amount,
                        userBalance.getAvailableAmount().add(amount),
                        OrderConstants.TYPE_USER_INCOME, "用户退款",
                        OrderConstants.USER_TYPE_USER, OrderConstants.ORDER_TYPE_REFUND
                );
            }

            // 系统用户扣款
            log.info("开始扣款，给系统扣款");
            boolean isDeducted = userBalanceService.deductBalance(PLATFORM_USER_ID, amount);
            if (isDeducted) {
                UserBalanceEntity platformBalance = userBalanceService.getBalanceByUserId(PLATFORM_USER_ID);
                boolean isSave = createAndSaveTransaction(
                        PLATFORM_USER_ID, activityArticle.getId(), amount,
                        platformBalance.getAvailableAmount().subtract(amount), OrderConstants.TYPE_PLATFORM_EXPENSE,
                        "用户退款", OrderConstants.USER_TYPE_PLATFORM, OrderConstants.ORDER_TYPE_REFUND
                );
                if (!isSave) {
                    throw new CampusException("保存交易记录失败", 201);
                }
            }
        }
        // 开始退积分
        if (activityArticle.getOrderNo() != null && !activityArticle.getOrderNo().isEmpty()) {
            BountyOrder bountyOrder = bountyOrderService.getByOrderNo(activityArticle.getOrderNo());
            if (bountyOrder != null) {
                pointsAccountService.addPoints(bountyOrder.getPaymentId(), bountyOrder.getPoints(), pointsMsg, null);
            }
        } else {
            log.info("订单号为空");
        }
    }

    @Async
    protected void handleOrderUpdateAmt(ActivityArticle article, BigDecimal amount, String msg, String pointsMsg) {
        log.info(msg);
        List<ActivityApply> applyList = applyService.list(new QueryWrapper<ActivityApply>().eq("art_id", article.getId()).eq("orders_status", "2"));
        if (applyList.isEmpty()) {
            return;
        }
        log.info("{}，共{}人", msg, applyList.size());
        for (ActivityApply apply : applyList) {
            UpdateWrapper<ActivityApply> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", apply.getId());
            updateWrapper.set("orders_status", "5");
            applyService.update(updateWrapper);
            handleOrderUpdateAmt(apply.getId(), apply.getUserId(), amount, msg, apply.getPoints(), pointsMsg);
        }
    }

    /**
     * 处理发布者修改价格的订单
     * 向相应用户退款
     *
     * @param id     活动文章id
     * @param userId 用户id
     * @param amount 退款金额
     * @param msg    订单描述
     * @param points 积分
     */
    private void handleOrderUpdateAmt(String id, String userId, BigDecimal amount, String msg, Integer points, String pointsMsg) {
        log.info("发布者修改价格开始退钱，给{}退钱", userId);
        boolean isAdded = userBalanceService.addBalance(userId, amount);
        if (isAdded) {
            UserBalanceEntity userBalance = userBalanceService.getBalanceByUserId(userId);
            createAndSaveTransaction(
                    userId,
                    id,
                    amount,
                    userBalance.getAvailableAmount().add(amount),
                    OrderConstants.TYPE_USER_INCOME,
                    msg,
                    OrderConstants.USER_TYPE_USER, OrderConstants.ORDER_TYPE_REFUND
            );
        }

        // 系统用户扣款
        log.info("发布者修改价格开始退钱，给系统扣款");
        boolean isDeducted = userBalanceService.deductBalance(PLATFORM_USER_ID, amount);
        if (isDeducted) {
            UserBalanceEntity platformBalance = userBalanceService.getBalanceByUserId(PLATFORM_USER_ID);
            boolean isSave = createAndSaveTransaction(
                    PLATFORM_USER_ID,
                    id,
                    amount,
                    platformBalance.getAvailableAmount().subtract(amount),
                    OrderConstants.TYPE_PLATFORM_EXPENSE,
                    msg,
                    OrderConstants.USER_TYPE_PLATFORM, OrderConstants.ORDER_TYPE_REFUND
            );
            if (!isSave) {
                throw new CampusException("保存交易记录失败", 201);
            }
        }
        if (points != null && points > 0) {
            pointsAccountService.minusPoints(userId, points, pointsMsg);
        }
    }

    // 公共方法：创建并保存交易记录
    private boolean createAndSaveTransaction(String userId, String txId, BigDecimal changeAmount, BigDecimal balanceAfterChange,
                                             String txType, String remark, String userType, String type) {
        log.info("开始保存交易记录，用户id{},业务id{},交易类型{}，用户类型{}", userId, txId, txType, userType);
        UserBalanceTransactionEntity transaction = new UserBalanceTransactionEntity();
        transaction.setUserId(userId);
        transaction.setTxId(userType.equals(OrderConstants.USER_TYPE_PLATFORM) ? "PL" + txId : txId);
        transaction.setChangeAmount(changeAmount);  // 微信单位为分
        transaction.setBalanceSnapshot(balanceAfterChange);
        transaction.setTxStatus(OrderConstants.TX_STATUS_SUCCESS);
        transaction.setTxType(txType);
        transaction.setRemark(remark);
        transaction.setUserType(userType);
        transaction.setType(type);
        boolean result = userBalanceTransactionService.save(transaction);
        log.info("保存交易结果：{}", result ? "成功" : "失败");
        return result;
    }

    /**
     * 获取收款用户的ID
     * 根据活动类型判断是买家还是卖家
     *
     * @param activityArticle 活动文章对象，包含用户ID和活动类型
     * @return 收款用户的ID
     */
    private String getRecipientUserId(ActivityArticle activityArticle) {
        return activityArticle.getType() == 1 ? activityArticle.getUserId() : activityArticle.getApplyId();
    }

    /**
     * 处理已完成状态的订单
     * 向相应用户打款
     *
     * @param activityArticle 活动文章对象，包含打款金额和用户信息
     */

    private void handleOrderCompleted(ActivityArticle activityArticle) {
        log.info("处理已完成状态的订单");
        String userId = getRecipientUserId(activityArticle);
        BigDecimal amount = activityArticle.getMoney();
        String userType = activityArticle.getType() == 1 ? "买家" : "卖家";

        log.info("开始打款，给{}打款,用户id{}", userType, userId);

        boolean isAdded = userBalanceService.addBalance(userId, amount);
        if (isAdded) {
            UserBalanceEntity userBalance = userBalanceService.getBalanceByUserId(userId);
            createAndSaveTransaction(
                    userId, activityArticle.getId(),
                    amount, userBalance.getAvailableAmount().add(amount),
                    OrderConstants.TYPE_USER_INCOME, "用户收款",
                    OrderConstants.USER_TYPE_USER, OrderConstants.ORDER_TYPE_RECEIVE
            );
        }

        // 系统用户扣款
        log.info("开始扣款，给系统扣款");
        boolean isDeducted = userBalanceService.deductBalance(PLATFORM_USER_ID, amount);
        if (isDeducted) {
            UserBalanceEntity platformBalance = userBalanceService.getBalanceByUserId(PLATFORM_USER_ID);
            createAndSaveTransaction(
                    PLATFORM_USER_ID, activityArticle.getId(),
                    amount, platformBalance.getAvailableAmount().subtract(amount),
                    OrderConstants.TYPE_PLATFORM_EXPENSE, "用户收款",
                    OrderConstants.USER_TYPE_PLATFORM, OrderConstants.ORDER_TYPE_RECEIVE
            );
        }
    }

    private QueryWrapper creatQueryWrapper() {
        QueryWrapper<ActivityArticle> queryWrapper = new QueryWrapper<>();
        // 根据时间倒序排列
        queryWrapper.orderByDesc("start_time");
        return queryWrapper;
    }
}
